﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.Formula.Functions;
using SkiaSharp;
using XW.Utils;
using static System.Net.Mime.MediaTypeNames;

namespace XW.Core
{ 
    /// <summary>
    /// 验证码帮助类
    /// </summary>
    public static  class CaptchaHelper
    {

        public static byte[] GenImage(string code, int width = 128, int height = 45) {
 
            Random random = new();

            using SKBitmap image = new(width, height, SKColorType.Bgra8888, SKAlphaType.Premul);
            using SKCanvas canvas = new(image);
            canvas.DrawColor(SKColors.White);

            //// 画干扰线
            //// 干扰线占图片面积的比例
            //decimal distractorLineRate = 0.000005M;
            //for (int i = 0; i < (width * height * distractorLineRate); i++)
            //{
            //    using SKPaint _drawStyle = new();
            //    _drawStyle.Color = new(Convert.ToUInt32(random.Next(int.MaxValue)));
            //    canvas.DrawLine(random.Next(0, width), random.Next(0, height), random.Next(0, width), random.Next(0, height), _drawStyle);
            //}
            // 绘制干扰线  
            using (var linePaint = new SKPaint())
            {
                // 半透明黑色  
                linePaint.Color = new SKColor(0, 0, 0, 128);
                linePaint.StrokeWidth = 1;
                linePaint.IsAntialias = true;
                 
                for (int i = 0; i < 5; i++) // 绘制5条干扰线  
                {
                    float x1 = 0;
                    float y1 = random.Next(height);
                    float x2 = width;
                    float y2 = random.Next(height);
                    canvas.DrawLine(x1, y1, x2, y2, linePaint);
                }
            }
            // 画文本
            using SKPaint drawStyle = new();
            drawStyle.Color = SKColors.Black;
            drawStyle.TextSize = height;
            drawStyle.IsAntialias = true; // 抗锯齿

            // 文本居中显示
            float textWidth = drawStyle.MeasureText(code);
            float x = (width - textWidth) / 2;
            float y = (height + drawStyle.TextSize) / 2; // 调整Y轴位置以居中

            // 绘制每个字符
            foreach (char c in code)
            {
                string character = c.ToString();
                float charWidth = drawStyle.MeasureText(character);
                float charRotation = random.Next(-15, 15); // 随机旋转角度

                canvas.Save();
                canvas.RotateDegrees(charRotation, x + charWidth / 2, y - drawStyle.TextSize / 2);
                canvas.DrawText(character, x, y, drawStyle);
                canvas.Restore();

                x += charWidth;
            }

            //// 绘制噪点
            //for (int i = 0; i < (width * height * 0.6); i++)
            //{
            //    image.SetPixel(random.Next(0, width), random.Next(0, height), new SKColor(Convert.ToUInt32(random.Next(int.MaxValue))));
            //}

            using var img = SKImage.FromBitmap(image);
            using SKData p = img.Encode(SKEncodedImageFormat.Png, 100);
            return p.ToArray();
        } 
        /// <summary>
        ///  随机生成验证码
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string CreateValidateCode(int len)
        {
            // 可选字符集  
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

            // 创建一个新的随机数生成器  
            Random random = new Random();

            // 生成验证码  
            string code = new string(Enumerable.Repeat(chars, len)
                .Select(s => s[random.Next(s.Length)]).ToArray());
            return code;
        }
        /// <summary>
        /// 生成验证码
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static string Gen(string id) { 
            string code = CreateValidateCode(4);
            CacheHelper.SetString(id,code);
            var img = GenImage(code);
            return Convert.ToBase64String(img);
        }
        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="id"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        public static bool Valid(string id,string val) { 
            string code = CacheHelper.GetString(id);
            if (val.IsNotNullAndEmpty() && code.IsNotNullAndEmpty() && val.ToUpper() == code.ToUpper())
            {
                return true;
            }
            // Console.WriteLine("val:{0},code:{1}",val,code);
            return false;
        }
    }
}
